package net.steam.easyjoboa.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;
import net.steam.easyjoboa.dao.BaseDao;
import net.steam.easyjoboa.entity.PageBean;
import net.steam.easyjoboa.entity.PageBeans;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class BaseDaoSupport<K extends Serializable, V extends Serializable> extends HibernateDaoSupport implements BaseDao<K, V> {

	
	@SuppressWarnings("unchecked")
	public K addEntity(V entity) throws Exception {
		return (K) getHibernateTemplate().save(entity);
	}

	public void deleteEntity(K key) throws Exception {
		getHibernateTemplate().delete(getHibernateTemplate().get(getEntityType(), key));
	}

	public void updateEntity(V entity) {
		getHibernateTemplate().update(entity);
	}

	public V findById(K key) {
		return getHibernateTemplate().get(getEntityType(), key);
	}

	@SuppressWarnings("unchecked")
	public List<V> find(String hql, Object... params) {
		return getHibernateTemplate().find(hql, params);
	}
	
	@SuppressWarnings("unchecked")
	protected Class<V> getEntityType() {
		return (Class<V>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[1];
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<V> find(final PageBean pb,final String hql,final Object... params) {
		return getHibernateTemplate().executeFind(new HibernateCallback(){

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				/*
				 * ͳ���ܼ�¼��
				 */
				String totalPageHql = "select count(*) " + hql.substring(hql.toLowerCase().indexOf("from"));
				Query totalQuery = session.createQuery(totalPageHql);
				for (int i = 0; i < params.length; i++) {
					totalQuery.setParameter(i, params[i]);
				}
				int total = Integer.parseInt(String.valueOf((Long)totalQuery.uniqueResult()));
				pb.setTotalRecords(total);
				/*
				 * ��ѯ��ҳ��¼
				 */
				Query query = session.createQuery(hql);
				for (int i = 0; i < params.length; i++) {
					query.setParameter(i, params[i]);
				}
				query.setFirstResult(pb.getFirstResult());
				query.setMaxResults(pb.getPageSize());
				List<V> list = query.list();
				return list;
			}
		});		
	}
	
	@SuppressWarnings("unchecked")
	public List<V> findByPage(PageBeans pb, String hql, Object... params) {
		Session session = getHibernateTemplate().getSessionFactory().openSession();		
		
		/*
		 * 缁熻鎬昏褰曟暟
		 */
		String totalPageHql = "select count(*) " + hql.substring(hql.toLowerCase().indexOf("from"));
		Query totalQuery = session.createQuery(totalPageHql);
		for (int i = 0; i < params.length; i++) {
			totalQuery.setParameter(i, params[i]);
		}
		/*
		 * 鏌ヨ鍒嗛〉璁板綍
		 */
		Query query = session.createQuery(hql);
		for (int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
		int total = Integer.parseInt(String.valueOf((Long)totalQuery.uniqueResult()));		
		
		if(total%pb.getPageSize()==0){
			pb.setTotalRecords(total/pb.getPageSize());
		}else{
			pb.setTotalRecords(total/pb.getPageSize()+1);
		}
		query.setFirstResult((pb.getCurrentPage()-1)*pb.getPageSize());
		query.setMaxResults(pb.getPageSize());
		List<V> list = query.list();
		session.close();
		return list;
	}


}
